# -*- coding:utf-8 -*-
#! /bin/python

import os,sys
import hashlib,io

from FileTree import Node,FileTree 

def cmp(a,b):
    return (a > b) - (a < b)
# scan files tree, computer the md5 for each dirs
# if files and dirs are included in one dir,
# the md5 is computer by each of md5 of files and each of md5 of dirs
def get_child_node_md5(node,md5_dirnames_map):
    cur_dir_md5=[]
    names = node.get_child_names()
    names = list(names)
    if (len(names) < 1) or ((len(names) == 1) and (names[0]=="..")) : #empty dir or file or root
        return node.get_data()
    
    for name in names:
        if name == "..":
            continue
        n = node.get_child_node(name)
        ret = ""
        if n.is_dir() == False:
            ret = n.get_data()
        else:
            ret = get_child_node_md5(n,md5_dirnames_map)
        cur_dir_md5.append(ret)
    cur_dir_md5.sort();
    
    m = hashlib.md5()
    for md5 in cur_dir_md5:
        m.update(md5.encode("utf-8"))
    md5_str = m.hexdigest()
    #print node.get_path(),md5_str,
    if md5_str not in md5_dirnames_map.keys():
        md5_dirnames_map[md5_str] = [node.get_full_path()]
    else:
        md5_dirnames_map[md5_str].append(node.get_full_path())
    return md5_str

def count_files_and_dirs_exclude_empty_dirs_in_dir(dir_path):
    li = os.listdir(dir_path)
    count = len(li)
    for i in li:
        _path = os.path.join(dir_path,i)
        if os.path.isdir(_path) and len(os.listdir(_path))==0:
            count=count-1
    return count

#FIXME:  
# if A={d,f,h,g} B={d,f,p}
# the input duplicated files are {d,f}
# this function return A and B are same dirs
# but as you see, it's not
# so add code to remove this same dirs
def compute_same_dir(fs):
    #FIXME:remove below code afa fix bug
    return {}
    _file_tree_root = FileTree()
    for i in fs.keys():
        for f in fs[i]:
            _file_tree_root.apply_path(f).set_data(i)
    #print _file_tree_root.dump().encode("utf8")
    
    #_node = _file_tree_root.get_node("/tmp/kkk/hhh/nnnn.txt")
    _node = _file_tree_root.get_node("")
    #print _node.get_path()
    
    md5_dirnames_map={}
    get_child_node_md5(_node,md5_dirnames_map)
    md5_dirnames_map1={}
    
    #remove unduplicated dir
    for k in md5_dirnames_map.keys():
        same_dirs = md5_dirnames_map[k]
        #print k,same_dirs[0],len(same_dirs)
        if len(same_dirs) < 2:
            continue
        md5_dirnames_map1[k] = same_dirs
    
    #remove the dir, if no dunplicated file found in this dir
    md5_dirnames_map2={}
    for k in md5_dirnames_map1.keys():
        #print k
        dirs=[]
        for i in md5_dirnames_map1[k]:
            count1 = len(_file_tree_root.get_node(i).get_child_names())-1
            count2 = count_files_and_dirs_exclude_empty_dirs_in_dir(i)
            #print count1,count2,i
            if count1 == count2:
                dirs.append(i)
            #print i.encode("utf8")
        if len(dirs) > 1:
            md5_dirnames_map2[k] = dirs
    #/a1/b1/c1  and /a2/b2/c2 are same
    #/a1/b1 and /a2/b2 are also same
    #remove the sub dirs
    
    #1 get all dirs
    all_dirs=[]
    for k in md5_dirnames_map2.keys():
        for i in md5_dirnames_map2[k]:
            all_dirs.append(i)
    #2 get the sub dirs which will remove
    sub_dirs=[]
    for d1 in all_dirs:
        len_d1 = len(d1)
        for d2 in all_dirs:
            len_d2 = len(d2)
            if len_d1 > len_d2:
                if cmp(d1[0:len_d2],d2) == 0:
                    sub_dirs.append(d1)
                    break
    #3 remove the sub dirs
    md5_dirnames_map3={}
    for k in md5_dirnames_map2.keys():
        dirs=[]
        for i in md5_dirnames_map2[k]:
            if i not in sub_dirs:
                dirs.append(i)
        if len(dirs) > 1:
            md5_dirnames_map3[k] = dirs
    
    #for k in md5_dirnames_map3.keys():
    #    print k
    #    for i in md5_dirnames_map3[k]:
    #        print i.encode("utf8")
    return md5_dirnames_map3

    
    
